/**
 * 圆形喷泉可视化器
 */
class CircularFountainVisualizer extends VisualizerInterface {
    constructor(canvas, ctx) {
        super(canvas, ctx);
        this.particles = [];
        this.centerX = 0;
        this.centerY = 0;
        this.maxRadius = 0;
        this.angleStep = 0;
    }

    getInfo() {
        return {
            name: 'Circular Fountain',
            description: '圆形向外喷泉效果',
            author: 'AudioNN',
            version: '1.0.0',
            category: 'particle'
        };
    }

    getDefaultSettings() {
        return {
            ...super.getDefaultSettings(),
            particleCount: 200,
            fountainHeight: 0.8,
            rotationSpeed: 0.01,
            particleLife: 100,
            gravityStrength: 0.3,
            colorMode: 'rainbow', // rainbow, gradient, single
            singleColor: '#4CAF50',
            innerRadius: 50,
            pulseEffect: true,
            trailEffect: true
        };
    }

    getConfigurableParams() {
        return [
            ...super.getConfigurableParams(),
            {
                key: 'particleCount',
                label: '粒子数量',
                type: 'range',
                min: 50,
                max: 500,
                step: 10,
                default: 200
            },
            {
                key: 'fountainHeight',
                label: '喷泉高度',
                type: 'range',
                min: 0.3,
                max: 1.0,
                step: 0.1,
                default: 0.8
            },
            {
                key: 'rotationSpeed',
                label: '旋转速度',
                type: 'range',
                min: 0,
                max: 0.05,
                step: 0.001,
                default: 0.01
            },
            {
                key: 'colorMode',
                label: '颜色模式',
                type: 'select',
                options: [
                    { value: 'rainbow', label: '彩虹色' },
                    { value: 'gradient', label: '渐变色' },
                    { value: 'single', label: '单色' }
                ],
                default: 'rainbow'
            },
            {
                key: 'pulseEffect',
                label: '脉冲效果',
                type: 'boolean',
                default: true
            },
            {
                key: 'trailEffect',
                label: '拖尾效果',
                type: 'boolean',
                default: true
            }
        ];
    }

    init(config = {}) {
        super.init(config);
        this.updateDimensions();
        this.initializeParticles();
        this.currentRotation = 0;
        return this;
    }

    updateDimensions() {
        const width = this.canvas.width / window.devicePixelRatio;
        const height = this.canvas.height / window.devicePixelRatio;
        
        this.centerX = width / 2;
        this.centerY = height / 2;
        this.maxRadius = Math.min(width, height) / 2 * this.settings.fountainHeight;
        this.angleStep = (Math.PI * 2) / this.settings.particleCount;
    }

    initializeParticles() {
        this.particles = [];
        for (let i = 0; i < this.settings.particleCount; i++) {
            this.particles.push(this.createParticle(i));
        }
    }

    createParticle(index) {
        const angle = index * this.angleStep;
        return {
            originalAngle: angle,
            currentAngle: angle,
            radius: this.settings.innerRadius,
            velocity: { x: 0, y: 0 },
            life: Math.random() * this.settings.particleLife,
            maxLife: this.settings.particleLife,
            size: Math.random() * 3 + 1,
            intensity: 0,
            trail: []
        };
    }

    render(frequencyData, cachedData = null, currentTime = 0) {
        // 清除画布或添加拖尾效果
        if (this.settings.trailEffect) {
            this.ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
            const width = this.canvas.width / window.devicePixelRatio;
            const height = this.canvas.height / window.devicePixelRatio;
            this.ctx.fillRect(0, 0, width, height);
        } else {
            this.clearCanvas();
        }

        const dataToUse = cachedData || frequencyData;
        if (!dataToUse) return;

        // 更新旋转
        this.currentRotation += this.settings.rotationSpeed;

        // 更新粒子
        this.updateParticles(dataToUse);

        // 绘制中心圆环
        this.drawCenterRing(dataToUse);

        // 绘制粒子
        this.drawParticles();

        // 绘制频谱环
        this.drawSpectrumRing(dataToUse);
    }

    updateParticles(frequencyData) {
        const dataPerParticle = frequencyData.length / this.particles.length;

        this.particles.forEach((particle, index) => {
            // 获取对应的频谱数据
            const dataIndex = Math.floor(index * dataPerParticle);
            const intensity = frequencyData[dataIndex] / 255;
            particle.intensity = intensity;

            // 更新角度
            particle.currentAngle = particle.originalAngle + this.currentRotation;

            // 根据音频强度计算喷射力
            const force = intensity * this.settings.sensitivity;
            const targetRadius = this.settings.innerRadius + force * this.maxRadius;

            // 粒子物理更新
            if (force > 0.1) {
                // 向外喷射
                const forceX = Math.cos(particle.currentAngle) * force * 5;
                const forceY = Math.sin(particle.currentAngle) * force * 5;
                
                particle.velocity.x += forceX;
                particle.velocity.y += forceY;
                particle.life = particle.maxLife; // 重置生命
            }

            // 应用重力和阻力
            particle.velocity.y += this.settings.gravityStrength;
            particle.velocity.x *= 0.95;
            particle.velocity.y *= 0.95;

            // 更新位置
            const currentX = this.centerX + Math.cos(particle.currentAngle) * particle.radius;
            const currentY = this.centerY + Math.sin(particle.currentAngle) * particle.radius;
            
            const newX = currentX + particle.velocity.x;
            const newY = currentY + particle.velocity.y;
            
            // 计算新的极坐标
            const dx = newX - this.centerX;
            const dy = newY - this.centerY;
            particle.radius = Math.sqrt(dx * dx + dy * dy);
            
            // 更新拖尾
            if (this.settings.trailEffect) {
                particle.trail.push({ x: newX, y: newY, alpha: 1.0 });
                if (particle.trail.length > 10) {
                    particle.trail.shift();
                }
                // 更新拖尾透明度
                particle.trail.forEach((point, i) => {
                    point.alpha = i / particle.trail.length;
                });
            }

            // 生命周期管理
            particle.life--;
            if (particle.life <= 0 || particle.radius < this.settings.innerRadius) {
                // 重置粒子到中心
                particle.radius = this.settings.innerRadius;
                particle.velocity = { x: 0, y: 0 };
                particle.life = particle.maxLife;
                particle.trail = [];
            }
        });
    }

    drawCenterRing(frequencyData) {
        // 计算平均强度
        const avgIntensity = frequencyData.reduce((sum, val) => sum + val, 0) / frequencyData.length / 255;
        
        // 绘制脉冲中心圆
        if (this.settings.pulseEffect) {
            const pulseRadius = this.settings.innerRadius * (1 + avgIntensity * 0.5);
            
            const gradient = this.ctx.createRadialGradient(
                this.centerX, this.centerY, 0,
                this.centerX, this.centerY, pulseRadius
            );
            
            const centerColor = this.getColorAtIntensity(avgIntensity, 0);
            gradient.addColorStop(0, centerColor);
            gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
            
            this.ctx.fillStyle = gradient;
            this.ctx.beginPath();
            this.ctx.arc(this.centerX, this.centerY, pulseRadius, 0, Math.PI * 2);
            this.ctx.fill();
        }

        // 绘制中心环
        this.ctx.strokeStyle = this.getColorAtIntensity(avgIntensity, 0);
        this.ctx.lineWidth = 3;
        this.ctx.beginPath();
        this.ctx.arc(this.centerX, this.centerY, this.settings.innerRadius, 0, Math.PI * 2);
        this.ctx.stroke();
    }

    drawParticles() {
        this.particles.forEach((particle, index) => {
            const x = this.centerX + Math.cos(particle.currentAngle) * particle.radius;
            const y = this.centerY + Math.sin(particle.currentAngle) * particle.radius;
            
            // 绘制拖尾
            if (this.settings.trailEffect && particle.trail.length > 1) {
                this.ctx.strokeStyle = this.getColorAtIntensity(particle.intensity, index);
                this.ctx.lineWidth = particle.size;
                this.ctx.beginPath();
                
                particle.trail.forEach((point, i) => {
                    if (i === 0) {
                        this.ctx.moveTo(point.x, point.y);
                    } else {
                        this.ctx.globalAlpha = point.alpha * particle.intensity;
                        this.ctx.lineTo(point.x, point.y);
                    }
                });
                this.ctx.stroke();
                this.ctx.globalAlpha = 1.0;
            }

            // 绘制粒子主体
            if (particle.intensity > 0.05) {
                const color = this.getColorAtIntensity(particle.intensity, index);
                
                // 发光效果
                this.ctx.shadowColor = color;
                this.ctx.shadowBlur = particle.intensity * 15;
                
                this.ctx.fillStyle = color;
                this.ctx.beginPath();
                this.ctx.arc(x, y, particle.size * (1 + particle.intensity), 0, Math.PI * 2);
                this.ctx.fill();
                
                this.ctx.shadowBlur = 0;
            }
        });
    }

    drawSpectrumRing(frequencyData) {
        const ringCount = 3;
        const ringSpacing = 30;
        
        for (let ring = 0; ring < ringCount; ring++) {
            const radius = this.settings.innerRadius + (ring + 1) * ringSpacing;
            const segments = 64;
            const anglePerSegment = (Math.PI * 2) / segments;
            
            this.ctx.beginPath();
            
            for (let i = 0; i < segments; i++) {
                const dataIndex = Math.floor((i / segments) * frequencyData.length);
                const intensity = frequencyData[dataIndex] / 255;
                
                const angle = i * anglePerSegment + this.currentRotation * (ring + 1);
                const lineLength = intensity * 20;
                
                const x1 = this.centerX + Math.cos(angle) * radius;
                const y1 = this.centerY + Math.sin(angle) * radius;
                const x2 = this.centerX + Math.cos(angle) * (radius + lineLength);
                const y2 = this.centerY + Math.sin(angle) * (radius + lineLength);
                
                this.ctx.strokeStyle = this.getColorAtIntensity(intensity, i + ring * segments);
                this.ctx.lineWidth = 2;
                this.ctx.globalAlpha = intensity;
                
                this.ctx.beginPath();
                this.ctx.moveTo(x1, y1);
                this.ctx.lineTo(x2, y2);
                this.ctx.stroke();
            }
            
            this.ctx.globalAlpha = 1.0;
        }
    }

    getColorAtIntensity(intensity, index) {
        switch (this.settings.colorMode) {
            case 'rainbow':
                const hue = (index * 360 / this.particles.length + this.currentRotation * 100) % 360;
                const saturation = 100;
                const lightness = 50 + intensity * 30;
                return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
                
            case 'gradient':
                const r = Math.floor(102 + intensity * 153); // 102 to 255
                const g = Math.floor(126 + intensity * 129); // 126 to 255  
                const b = Math.floor(234 + intensity * 21);  // 234 to 255
                return `rgb(${r}, ${g}, ${b})`;
                
            case 'single':
                const alpha = 0.3 + intensity * 0.7;
                // 处理颜色格式，支持 hex、rgb、rgba
                const color = this.settings.singleColor;
                if (color.startsWith('#')) {
                    // Hex to rgba
                    const hex = color.slice(1);
                    const r = parseInt(hex.slice(0, 2), 16);
                    const g = parseInt(hex.slice(2, 4), 16);
                    const b = parseInt(hex.slice(4, 6), 16);
                    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
                } else if (color.startsWith('rgb(')) {
                    // rgb to rgba
                    return color.replace('rgb(', 'rgba(').replace(')', `, ${alpha})`);
                } else if (color.startsWith('rgba(')) {
                    // 替换 alpha 值
                    return color.replace(/,\s*[\d.]+\)$/, `, ${alpha})`);
                }
                return `rgba(76, 175, 80, ${alpha})`; // fallback
                
            default:
                return this.settings.primaryColor;
        }
    }

    resize(width, height) {
        this.updateDimensions();
        this.initializeParticles();
    }
}

// 注册可视化器到全局注册表
if (typeof window !== 'undefined') {
    if (!window.visualizerRegistrations) {
        window.visualizerRegistrations = [];
    }
    window.visualizerRegistrations.push({
        id: 'circular-fountain',
        class: CircularFountainVisualizer
    });
}

window.CircularFountainVisualizer = CircularFountainVisualizer;
